package univ.bme.accounting.dao;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.NamedQuery;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Root;

import org.hibernate.criterion.Order;

import com.google.common.base.Predicate;

import univ.bme.accounting.domain.Transaction;

@Stateless
public class TransactionDAOImpl extends GenericDAOImpl<Transaction> implements
		TransactionDAO {

	public TransactionDAOImpl() {
		super(Transaction.class);
	}

	public void delete(Transaction transaction) {
		super.delete(transaction.getId(), Transaction.class);
	}

	public List<Transaction> findTransactionsForUser(int userId) {
		CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
		CriteriaQuery<Transaction> criteriaQuery = criteriaBuilder
				.createQuery(Transaction.class);
		Root<Transaction> entityRoot = criteriaQuery.from(Transaction.class);
		criteriaQuery.where(criteriaBuilder.equal(entityRoot.get("user"),
				userId));
		criteriaQuery.orderBy(criteriaBuilder.desc(entityRoot.get("date")));
		criteriaQuery.select(entityRoot);
		List<Transaction> c = em.createQuery(criteriaQuery).getResultList();
		return c;
	}

	@Override
	public List<Transaction> findTransactionsForUserAndYear(int userId, int year) {
		CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
		CriteriaQuery<Transaction> criteriaQuery = criteriaBuilder
				.createQuery(Transaction.class);
		Root<Transaction> entityRoot = criteriaQuery.from(Transaction.class);
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.WEEK_OF_YEAR, 1);
		cal.set(Calendar.DAY_OF_WEEK, 1);

		Date start = cal.getTime();

		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, 11);
		cal.set(Calendar.DAY_OF_MONTH, 31);

		Date end = cal.getTime();

		criteriaQuery.where(criteriaBuilder.and(criteriaBuilder.equal(
				entityRoot.get("user"), userId), criteriaBuilder.between(
				entityRoot.<Date> get("date"), start, end)));
		criteriaQuery.orderBy(criteriaBuilder.desc(entityRoot.get("date")));
		criteriaQuery.select(entityRoot);
		List<Transaction> c = em.createQuery(criteriaQuery).getResultList();
		return c;
	}
	
	public List<Integer> findAvailableYears(int userId) {
		List<Transaction> transactions =this.findTransactionsForUser(userId);
		List<Integer> results = new ArrayList<Integer>();
		for(Transaction tr : transactions){
			Calendar cal = Calendar.getInstance();
			cal.setTime(tr.getDate());
			if(!results.contains(cal.get(Calendar.YEAR))){
				results.add(cal.get(Calendar.YEAR));
			}
		}
		return results;
	}
}